<template>
  <BasicTree
    ref="treeElRef"
    v-bind="getBindValue"
    :checkStrictly="true"
    :clickRowToExpand="false"
    :api="props.api && loadTreeData"
    :params="props.params"
    :immediate="props.immediate"
    :selectedKeys="currState.selectedKeys"
    :expandedKeys="currState.expandedKeys"
    :autoExpandParent="currState.autoExpandParent"
    :beforeRightClick="getRightMenuList"
    @reload="handleReload"
    @select="handleSelect"
    @expand="handleExpand"
    @search="handleSearch"
  />
</template>

<script lang="ts" setup>
  import { computed, unref, ref, watchEffect, watch, nextTick } from "vue"
  import { useMessage } from "/@/hooks/web/useMessage"
  import { isFunction } from "/@/utils/is"
  import { BasicTree, ContextMenuItem, ContextMenuOptions } from "/@/components/Tree"
  import { treeProps } from "./props"
  import { useAttrs } from "/@/hooks/core/useAttrs"
  import { flatten as flattenTree } from "/@/utils/helper/treeHelper"

  const props = defineProps(treeProps)
  const emit = defineEmits(["select", "add-child", "edit", "delete"])
  const { createMessage } = useMessage()
  // get component class
  const attrs = useAttrs({ excludeDefaultKeys: false })

  interface CurrState {
    autoExpandParent?: boolean
    selectedKeys: any[]
    treeData: any[]
    expandedKeys?: any[]
    flattenData?: any[]
    isFirstLoad?: boolean
    searchKeyWord?: string
  }
  const currState = ref<CurrState>({
    // 是否自动展开父级
    autoExpandParent: true,
    // 当前选中的项
    selectedKeys: [],
    treeData: [],
    flattenData: [],
    // 当前展开的项
    expandedKeys: [],
    // 是否为第一次加载
    isFirstLoad: true,
    // 搜索关键字
    searchKeyWord: "",
  })
  const stateValue = currState.value
  const treeElRef = ref<any>()

  const loadTreeData = async (params: any) => {
    const { api, searchField } = props
    if (!api || !isFunction(api)) {
      console.log("api is not function")
      return []
    }

    stateValue.treeData = []

    const reqParams: any = { ...params }
    reqParams[searchField] = stateValue.searchKeyWord
    const data = await api(reqParams)
    if (!data || data.length === 0) {
      return []
    }

    if (Array.isArray(data)) {
      stateValue.treeData = data
      autoExpandParentNode()
    }

    if (stateValue.isFirstLoad) {
      stateValue.isFirstLoad = false
      handleReload()
    }
    return data
  }

  // get inherit binding value
  const { showIcon, showLine, toolbar, title, search } = unref(props)
  const getBindValue = computed(() => ({
    ...unref(attrs),
    showIcon,
    showLine,
    treeData: stateValue.treeData,
    toolbar,
    title,
    search,
  }))

  // 自动展开父节点，只展开一级
  const autoExpandParentNode = () => {
    if (stateValue.expandedKeys && stateValue.expandedKeys.length > 0) {
      console.log("stateValue.treeData", stateValue.treeData)

      const node = stateValue.flattenData?.find((e, index) => e.id === stateValue.expandedKeys[0])
      setSelectedKey(props.expandedKeys[0] as any, node)
      return
    }
    let keys: Array<any> = []
    stateValue.treeData.forEach((item, index) => {
      if (item.children && item.children.length > 0) {
        keys.push(item.key)
      }
      if (index === 0) {
        // 默认选中第一个
        setSelectedKey(item.id, item)
      }
    })
    if (keys.length > 0) {
      stateValue.expandedKeys = keys
    }
  }

  const getRightMenuList = (node: any): ContextMenuOptions => {
    const { enableAddChird, enableDelete, enableEdit, deleteApi } = props
    const { showAddSub = true, showEdit = true, showDelete = true } = node
    const menuList = [
      {
        label: "添加下级",
        show: showAddSub && enableAddChird,
        handler: () => {
          console.log("点击了新增", node)
          emit("add-child", node)
        },
      },
      {
        label: "编辑",
        show: showEdit && enableEdit,
        handler: () => {
          console.log("点击了编辑", node)
          emit("edit", node)
        },
      },
      {
        label: "删除",
        show: showDelete && enableDelete,
        handler: async () => {
          if (!deleteApi || !isFunction(deleteApi)) return
          console.log("点击了删除", node)
          await deleteApi({ id: node.id, name: node.title }, () => {
            createMessage.success("删除成功")
            handleReload()
          })
        },
      },
    ]
    const items = menuList.filter((e) => e.show)
    return { items, styles: { width: 100, zIndex: 10000 } }
  }

  const handleReload = () => {
    if (stateValue.treeData.length > 0) {
      emit("select", stateValue.treeData[0].id, stateValue.treeData[0])
    }
  }

  /**
   * 设置当前选中的行
   */
  function setSelectedKey(key: string, node?: object) {
    stateValue.selectedKeys = [key]
    if (key) {
      emit("select", key, node)
    }
  }

  // 树展开事件
  const handleExpand = (keys) => {
    stateValue.autoExpandParent = false
    stateValue.expandedKeys = keys
  }

  // 搜索事件
  const handleSearch = (value: string) => {
    stateValue.searchKeyWord = value
  }

  // 树选择事件
  const handleSelect = (selKeys, event) => {
    if (selKeys.length > 0 && stateValue.selectedKeys[0] !== selKeys[0]) {
      setSelectedKey(selKeys[0], event.selectedNodes[0])
    } else {
      // 这样可以防止用户取消选择
      setSelectedKey(stateValue.selectedKeys[0])
    }
  }

  const reload = () => {
    nextTick(() => {
      console.log("reload data")
      treeElRef.value && treeElRef.value.reload()
    })
  }

  watch(
    () => props.expandedKeys,
    () => {
      nextTick(async () => {
        if (props.expandedKeys) {
          stateValue.expandedKeys = props.expandedKeys
        }

        if (props.treeData && stateValue.treeData !== props.treeData) {
          stateValue.treeData = props.treeData

          stateValue.flattenData = [] as any[]
          flattenTree(props.treeData, stateValue.flattenData)
          autoExpandParentNode()
        }
      })
    },
    {
      immediate: true,
    }
  )

  // watchEffect(() => {
  // })

  defineExpose({
    reload,
  })
</script>
